//db库
//实例化mongoclient 传入数据库连接地址
const Config = require("./config.js");

const MongoClient = require("mongodb").MongoClient;
const ObjectID = require("mongodb").ObjectID;

class Db {
    static getInstance() {
        //单例,多次实例化不共享的原因
        if (!Db.instance) {
            Db.instance = new Db();
        }

        return Db.instance;
    }

    constructor() {
        this.dbClient = "";
        this.connect();
    }
    //链接数据库

    connect() {
        return new Promise((resolve, reject) => {
            //避免每次调用方法都会重连
            if (!this.dbClient) {

                MongoClient.connect(Config.url, { useUnifiedTopology: true }, (err, client) => {
                    if (err) {
                        reject(err);
                    } else {
                        const db = client.db(Config.dbName);
                        this.dbClient = db;
                        resolve(this.dbClient);
                    }
                });
            } else {
                resolve(this.dbClient);
            }
        });
    }
    find(collectionName, json) {
        return new Promise((resolve, reject) => {
            this.connect().then((db) => {
                //查找语句
                const res = db.collection(collectionName).find(json);
                res.toArray((err, docs) => {
                    if (err) {
                        reject(err);
                        return;
                    }

                    resolve(docs);
                });
            });
        });
    }
    count(collectionName, json) {
        return new Promise((resolve, reject) => {
            this.connect().then((db) => {
                //查找语句
                const res = db.collection(collectionName).find(json).count();
                if (res){
                    resolve(res);
                }else {
                    reject(res)
                }
            });
        });
    }
    findLimit(collectionName, json,total,pageSize) {
        return new Promise((resolve, reject) => {
            this.connect().then((db) => {
                //查找语句
                const res = db.collection(collectionName).find(json).limit(total?total:10).skip(total*(pageSize?pageSize-1:0));
                res.toArray((err, docs) => {
                    if (err) {
                        reject(err);
                        return;
                    }

                    resolve(docs);
                });
            });
        });
    }

    findSort(collectionName, json,total,pageSize) {
        return new Promise((resolve, reject) => {
            this.connect().then((db) => {
                //查找语句
                const res = db.collection(collectionName).find(json).sort({"like":-1}).limit(total?total:10).skip(total*(pageSize?pageSize-1:0));
                res.toArray((err, docs) => {
                    if (err) {
                        reject(err);
                        return;
                    }

                    resolve(docs);
                });
            });
        });
    }
    update(collectionName, json1, json2) {
        return new Promise((resolve, reject) => {
            this.connect().then((db) => {
                db.collection(collectionName).updateOne(
                    json1, { $set: json2 },
                    (err, data) => {
                        if (err) {
                            reject(err);
                        } else {
                            resolve(data);
                        }
                    }
                );
            });
        });
    }

    insert(collectionName, json) {
        return new Promise((resolve, reject) => {
            this.connect().then((db) => {
                db.collection(collectionName).insertOne(json, (err, data) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(data);
                    }
                });
            });
        });
    }

    remove(collectionName, json) {
        return new Promise((resolve, reject) => {
            this.connect().then((db) => {
                db.collection(collectionName).removeOne(json, (err, data) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(data);
                    }
                });
            });
        });
    }

    getObjectID(id) {
        return new ObjectID(id);
    }
}

module.exports = Db.getInstance();
